package com.demo.app.service;

import com.demo.app.enums.CustomExceptionType;
import com.demo.app.exception.CustomException;
import com.demo.app.util.JwtTokenUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author wangzhuangzhuang
 * @DESC: 核心的Token业务逻辑写在JwtAuthService中
 * - login方法中首先使用用户名、密码进行登录验证。如果验证失败抛出AuthenticationException异常。如果验证成功，程序继续向下走，生成JWT响应给前端；
 * - refreshToken方法只有在JWT token没有过期的情况下才能刷新，过期了就不能刷新了，需要重新登录；
 * @date 2022-02-15 15:08
 */
@Service
public class JwtAuthService {

	@Resource
	private AuthenticationManager authenticationManager;
	@Resource
	private UserDetailsService userDetailsService;
	@Resource
	private JwtTokenUtil jwtTokenUtil;

	public String login(String username, String password) throws CustomException {
		try {
			//使用用户名密码进行登录验证
			UsernamePasswordAuthenticationToken upToken =
					new UsernamePasswordAuthenticationToken(username, password);
			Authentication authentication = authenticationManager.authenticate(upToken);
			SecurityContextHolder.getContext().setAuthentication(authentication);
		} catch (AuthenticationException e) {
			throw new CustomException(CustomExceptionType.USER_INPUT_ERROR,
					"用户名或密码不正确");
		}

		//生成JWT
		UserDetails userDetails = userDetailsService.loadUserByUsername(username);
		return jwtTokenUtil.generateToken(userDetails);
	}

	public String refreshToken(String oldToken) {
		if (!jwtTokenUtil.isTokenExpired(oldToken)) {
			return jwtTokenUtil.refreshToken(oldToken);
		}
		return null;
	}
}